//
//  MyWebView.m
//  app端如何和H5交互
//
//  Created by clz on 2019/10/15.
//  Copyright © 2019 clz. All rights reserved.
//

#import "MyWebView.h"
#import <WebKit/WebKit.h>
#import <Masonry.h>
#import "WeakWebViewScriptMessageDelegate.h"

@interface MyWebView()<WKNavigationDelegate,WKScriptMessageHandler>

@property(nonatomic,strong)WKWebView *webView;

@property(nonatomic,strong)UIButton *nativeButton;

@end

@implementation MyWebView

- (instancetype)init
{
    self = [super init];
    if (self) {
//        self.myWebViewVM = [[MyWebViewVM alloc]init];
//        [self.myWebViewVM addObserver:self forKeyPath:@"url" options:NSKeyValueObservingOptionNew context:nil];
        
        //配置
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        WKPreferences *preference = [[WKPreferences alloc]init];
        preference.javaScriptEnabled = YES;
        config.preferences = preference;
        config.applicationNameForUserAgent = @"iphoneOrIpad";

        //自定义的WKScriptMessageHandler
        WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
        
        //这个类主要用来做native与JavaScript的交互管理
        
        WKUserContentController * wkUController = [[WKUserContentController alloc] init];
        // 注入JS对象名称AppModel，当JS通过AppModel来调用时，
        // 我们可以在WKScriptMessageHandler代理中接收到
        [wkUController addScriptMessageHandler:weakScriptMessageDelegate  name:@"AppModel"];
        
        config.userContentController = wkUController;
        
    //以下代码适配文本大小，由UIWebView换为WKWebView后，会发现字体小了很多，这应该是WKWebView与html的兼容问题，解决办法是修改原网页，要么我们手动注入JS
        NSString *jSString = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
        //用于进行JavaScript注入
        WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];

        [config.userContentController addUserScript:wkUScript];


        self.webView = [[WKWebView alloc]initWithFrame:CGRectZero configuration:config];
        self.webView.navigationDelegate = self;
        [self addSubview:self.webView];
        [self.webView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.right.equalTo(self);
            make.height.mas_equalTo(200);
        }];
        
        self.nativeButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [self.nativeButton addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
        [self.nativeButton setTitle:@"原生按钮" forState:UIControlStateNormal];
        [self.nativeButton setBackgroundColor:[UIColor yellowColor]];
        [self.nativeButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [self addSubview:self.nativeButton];
        [self.nativeButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.equalTo(self);
            make.top.equalTo(self.webView.mas_bottom).offset(30);
            make.height.mas_equalTo(50);
        }];
        
        NSString *path = [[NSBundle mainBundle] pathForResource:@"TEST.html" ofType:nil];
        NSString *htmlString = [[NSString alloc]initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        //加载本地html文件
        [self.webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
        
        
    }
    return self;
}


- (void)action:(UIButton *)sender{
    
    /*
     WKUserContentController允许在DOM树开始加载时添加要注入的WKUserScript或完成加载。相反，evaluateJavaScript允许应用程序在 任何 时按需执行javascript代码段。
     */
    
    //OC调用JS  changeColor()是JS方法名，completionHandler是异步回调block
    NSString *jsString = [NSString stringWithFormat:@"changeColor('%@')", @"yellow"];
    [self.webView evaluateJavaScript:jsString completionHandler:^(id _Nullable data, NSError * _Nullable error) {
        NSLog(@"改变HTML的背景色");
    }];
    
//    //改变字体大小 调用原生JS方法
//    NSString *jsFont = [NSString stringWithFormat:@"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '%d%%'", arc4random()%99 + 100];
//    [_webView evaluateJavaScript:jsFont completionHandler:nil];
    
}


#pragma mark-WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    NSLog(@"触发了js");
    
    NSLog(@"name = %@",message.name);
    
    //用message.body获得JS传出的参数体
    NSDictionary * parameter = message.body;
    
    NSLog(@"parameter = %@",parameter);
    
    //JS调用OC
    if([message.name isEqualToString:@"AppModel"]){
        [self.nativeButton setBackgroundColor:[UIColor redColor]];
    }
}

#pragma mark-WKWebView
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"页面开始加载时调用");
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
//    [self.progressView setProgress:0.0f animated:NO];
    NSLog(@"页面加载失败时调用");
}

- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    NSLog(@"当内容开始返回时调用");
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
//    [self getCookie];
    NSLog(@"页面加载完成之后调用");
}

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
//    [self.progressView setProgress:0.0f animated:NO];
    NSLog(@"提交发生错误时调用");
}

- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"接收到服务器跳转请求即服务重定向时之后调用");
}

// 根据WebView对于即将跳转的HTTP请求头信息和相关信息来决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
    NSString * urlStr = navigationAction.request.URL.absoluteString;
    NSLog(@"发送跳转请求：%@",urlStr);
    decisionHandler(WKNavigationActionPolicyAllow);

    //自己定义的协议头
//    NSString *htmlHeadString = @"github://";
//    if([urlStr hasPrefix:htmlHeadString]){
//        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"通过截取URL调用OC" message:@"你想前往我的Github主页?" preferredStyle:UIAlertControllerStyleAlert];
//        [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//        }])];
//        [alertController addAction:([UIAlertAction actionWithTitle:@"打开" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//            NSURL * url = [NSURL URLWithString:[urlStr stringByReplacingOccurrencesOfString:@"github://callName_?" withString:@""]];
//            [[UIApplication sharedApplication] openURL:url];
//        }])];
//        [self presentViewController:alertController animated:YES completion:nil];
//        decisionHandler(WKNavigationActionPolicyCancel);
//    }else{
//        decisionHandler(WKNavigationActionPolicyAllow);
//    }
}

// 根据客户端受到的服务器响应头以及response相关信息来决定是否可以跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    NSString * urlStr = navigationResponse.response.URL.absoluteString;
    NSLog(@"当前跳转地址：%@",urlStr);
    //允许跳转
    decisionHandler(WKNavigationResponsePolicyAllow);
    //不允许跳转
    //decisionHandler(WKNavigationResponsePolicyCancel);
}
//需要响应身份验证时调用 同样在block中需要传入用户身份凭证
//- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
//    //用户身份信息
//
//    NSLog(@"验证身份");
//
//    NSURLCredential * newCred = [[NSURLCredential alloc] initWithUser:@"user123" password:@"123" persistence:NSURLCredentialPersistenceNone];
//    //为 challenge 的发送方提供 credential
//    [challenge.sender useCredential:newCred forAuthenticationChallenge:challenge];
//    completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
//}

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
    
    NSLog(@"进程被终止时调用");
}


- (void)dealloc{
    
    [[self.webView configuration].userContentController removeScriptMessageHandlerForName:@"AppModel"];
}

@end
